﻿using Rw.Core.Common.Paging;
using Rw.Core.ORM.Domain;
using WH.Common.Paging;
using System.Linq.Expressions;

namespace WH.Services.BaseService
{
    public interface IBaseService<TAggregateRoot> where TAggregateRoot : class, IAggregateRoot<string>
    {
        /// <summary>
        /// 根据主键查找实体
        /// </summary>
        /// <param name="key">实体的主键</param>
        /// <returns>返回实体结果的异步任务</returns>
        Task<TAggregateRoot> FindByIdAsync(string key, bool withCache = false);

        /// <summary>
        /// 根据条件查找第一个实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns>返回实体结果的异步任务</returns>
        Task<TAggregateRoot> FirstOrDefaultAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false);

        /// <summary>
        /// 查找满足条件的实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns>返回实体列表结果的异步任务</returns>
        Task<IEnumerable<TAggregateRoot>> FindAllAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false);

        /// <summary>
        /// 分页查找所有实体
        /// </summary>
        /// <param name="orderByKeySelector">选择用于分页前排序的键</param>
        /// <param name="orderByType">排序类型</param>
        /// <param name="pager">分页器</param>
        /// <returns></returns>
        Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false);

        /// <summary>
        /// 分页查找满足条件的实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <param name="orderByKeySelector">选择用于分页前排序的键</param>
        /// <param name="orderByType">排序类型</param>
        /// <param name="pager">分页器</param>
        /// <returns></returns>
        Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, bool>> predicate, Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false);

        /// <summary>
        /// 分页查找满足条件的实体（自定义排序字段）
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="pager"></param>
        /// <param name="withCache"></param>
        /// <returns></returns>
        Task<IPagedList<TAggregateRoot>> PagedFindAllAsync(Expression<Func<TAggregateRoot, bool>> predicate, PageParam pager, bool withCache = false);

        /// <summary>
        /// 判断是否存在指定主键的实体
        /// </summary>
        /// <param name="key">实体的主键</param>
        /// <returns>返回是否存在的异步任务</returns>
        Task<bool> ExistsAsync(string key);

        /// <summary>
        /// 判断是否存在满足条件的实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(Expression<Func<TAggregateRoot, bool>> predicate);

        /// <summary>
        /// 判断是否存在实体
        /// </summary>
        /// <returns>是否存在</returns>
        Task<bool> AnyAsync();

        /// <summary>
        /// 判断是否存在满足条件的实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns>是否存在</returns>
        Task<bool> AnyAsync(Expression<Func<TAggregateRoot, bool>> predicate);

        /// <summary>
        /// 计算实体个数
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns>条数</returns>
        Task<int> CountAsync(Expression<Func<TAggregateRoot, bool>>? predicate = default);

        /// <summary>
        /// 创建实体
        /// </summary>
        /// <param name="entity">新的实体</param>
        /// <returns>已创建的实体</returns>
        Task<int> CreateAsync(TAggregateRoot entity);

        /// <summary>
        /// 批量创建实体
        /// </summary>
        /// <param name="entities">新的实体集合</param>
        /// <returns>已创建的实体集合</returns>
        Task<int> CreateAsync(IEnumerable<TAggregateRoot> entities);

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity">待更新的实体</param>
        /// <returns></returns>
        Task<int> UpdateAsync(TAggregateRoot entity);

        /// <summary>
        /// 批量更新实体
        /// </summary>
        /// <param name="entities">待更新的实体集合</param>
        /// <returns></returns>
        Task<int> UpdateAsync(IEnumerable<TAggregateRoot> entities);

        /// <summary>
        /// 更新指定列
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        Task<int> UpdateColumnsAsync(TAggregateRoot entity, Expression<Func<TAggregateRoot, object>> columns);

        /// <summary>
        /// 保存实体
        /// </summary>
        /// <param name="entity">待保存的实体</param>
        /// <returns></returns>
        Task<int> SaveAsync(TAggregateRoot entity);

        /// <summary>
        /// 批量保存实体
        /// </summary>
        /// <param name="entities">待保存的实体集合</param>
        /// <returns></returns>
        Task<int> SaveAsync(IEnumerable<TAggregateRoot> entities);

        /// <summary>
        /// 根据主键删除实体
        /// </summary>
        /// <param name="key">待删除实体的主键</param>
        /// <returns></returns>
        Task<int> RemoveByIdAsync(string key);

        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="entity">待删除的实体</param>
        /// <returns></returns>
        Task<int> RemoveAsync(TAggregateRoot entity);

        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="entities">待删除的实体集合</param>
        /// <returns></returns>
        Task<int> RemoveAsync(IEnumerable<TAggregateRoot> entities);

        /// <summary>
        /// 删除满足条件的实体
        /// </summary>
        /// <param name="predicate">条件谓词</param>
        /// <returns></returns>
        Task<int> RemoveAsync(Expression<Func<TAggregateRoot, bool>> predicate);


        //Task<IEnumerable<TAggregateRoot>> FindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>>? predicate = null, bool withCache = false);

        //Task<IPagedList<TAggregateRoot>> PagedFindAllWithOrgContextAsync(Expression<Func<TAggregateRoot, bool>> predicate, Expression<Func<TAggregateRoot, object>> orderByKeySelector, OrderByMode orderByType, Pager pager, bool withCache = false);

    }
}
